"""
Case Type   : standby_statement_history
Case Name   : 传参个数为1,only_slow值为null,T2值为null,T1值比在备机上执行查询操作晚,查询结果预期为0
Create At   : 2022/10/11
Owner       : @li-xin12345
Description :
    1.主机建表
    2.插入40W数据
    3.备机上查询数据
    4.备机上查询pg_class表内容
    5.备机上查询,函数传参仅为T1,值比在备机上执行查询操作晚
    6.清理环境
Expect      :
    1.建表成功
    2.插入数据成功
    3.查询成功
    4.查询成功
    5.查询成功，查询数量为0
    6.清理环境成功
History     :
    Modified: by @zou_jialiang050 at 2023/02/18 备机查询前增加等待时间
    Modified: by @haomeng at 2024/12/06 单环境性能问题，备机查询前增加等待时间
"""
import os
import time
import unittest
from testcase.utils.Logger import Logger
from testcase.utils.Common import Common
from testcase.utils.CommonSH import CommonSH
from testcase.utils.Constant import Constant
from yat.test import Node

primary_sh = CommonSH('PrimaryDbUser')


@unittest.skipIf(1 == primary_sh.get_node_num(),
                 'Single node, and subsequent codes are not executed.')
class StandbyStatementHistory(unittest.TestCase):
    def setUp(self):
        self.logger = Logger()
        self.logger.info(f"-----{os.path.basename(__file__)} start-----")
        self.primary_node = Node('PrimaryDbUser')
        self.primary_sh = CommonSH('PrimaryDbUser')
        self.standby_sh = CommonSH('Standby1DbUser')
        self.constant = Constant()
        self.common = Common()
        self.table_name = 't_standby_statement_history_0005'
        self.enable_stmt = 'enable_stmt_track'
        self.enable_stmt_default = self.common.show_param(self.enable_stmt)
        self.log_min = 'log_min_duration_statement'
        self.log_min_default = self.common.show_param(self.log_min)

    def test_standby_statement_history(self):
        text = "-----前置条件:修改参数;expect:修改参数成功-----"
        self.logger.info(text)
        if self.enable_stmt_default != 'on':
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.enable_stmt}=on')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.enable_stmt)
        self.assertEquals(show_msg, 'on', '执行失败' + text)
        if self.log_min_default != '20ms':
            result = self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_min}=20ms')
            self.assertTrue(result, '执行失败' + text)
        show_msg = self.common.show_param(self.log_min)
        self.assertEquals(show_msg, '20ms', '执行失败' + text)

        text = "-----step1:主机建表;expect:建表成功-----"
        self.logger.info(text)
        create_cmd = f"drop table if exists {self.table_name};" \
            f"create table {self.table_name}(id1 int);"
        create_msg = self.primary_sh.execut_db_sql(create_cmd)
        self.logger.info(create_msg)
        self.assertIn(self.constant.TABLE_DROP_SUCCESS,
                      create_msg, '执行失败' + text)
        self.assertIn(self.constant.TABLE_CREATE_SUCCESS,
                      create_msg, '执行失败' + text)

        text = "-----step2:插入40W数据;expect:插入数据成功-----"
        self.logger.info(text)
        insert_cmd = f"insert into {self.table_name} " \
            f"values (generate_series(1,400000));"
        insert_msg = self.primary_sh.execut_db_sql(insert_cmd)
        self.logger.info(insert_msg)
        self.assertIn(self.constant.INSERT_SUCCESS_MSG,
                      insert_msg, '执行失败' + text)
        time.sleep(15)

        text = "-----step3:备机上查询数据;expect:查询成功-----"
        self.logger.info(text)
        sql_cmd = f"select count(*) from {self.table_name};"
        sql_msg = self.standby_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        self.assertIn('400000', sql_msg, '执行失败' + text)

        text = "-----step4:备机上查询pg_class表内容;expect:查询成功-----"
        self.logger.info(text)
        sql_cmd = f"select * from pg_class " \
            f"where relname like '%statement_history%';"
        sql_msg = self.standby_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        self.assertIn('(4 rows)', sql_msg, '执行失败' + text)
        time.sleep(15)

        text = "-----step5:备机上查询,函数传参仅为T1,值比在备机上执行查询操作晚; " \
               "expect:查询成功，查询数量为0-----"
        self.logger.info(text)
        query_date_cmd = 'date "+%Y-%m-%d %H:%M:%S"'
        current_time = self.primary_node.sh(query_date_cmd).result()
        self.logger.info(current_time)
        sql_cmd = f"select date '{current_time}' + interval '10min' " \
            f"as result;"
        sql_msg = self.primary_sh.execut_db_sql(sql_cmd)
        self.logger.info(sql_msg)
        time_1 = sql_msg.splitlines()[-2].strip()
        self.logger.info(time_1)
        sql_cmd = f"set track_stmt_stat_level='l2,l2';" \
                  f"select pg_sleep(15);" \
            f"select * from dbe_perf.standby_statement_history" \
            f"(null, '{time_1}', null);"
        sql_msg = self.standby_sh.execut_db_sql(sql_cmd, dbname='postgres')
        self.logger.info(sql_msg)
        self.assertIn(self.constant.SET_SUCCESS_MSG, sql_msg, '执行失败' + text)
        self.assertIn('(0 rows)', sql_msg, '执行失败' + text)

    def tearDown(self):
        text_1 = "-----step6:清理环境;expect:清理环境成功-----"
        self.logger.info(text_1)
        drop_cmd = f"drop table {self.table_name} cascade;"
        drop_msg = self.primary_sh.execut_db_sql(drop_cmd)
        self.logger.info(drop_msg)
        text_2 = "-----恢复参数;expect:恢复参数成功-----"
        self.logger.info(text_2)
        enable_stmt_current = self.common.show_param(self.enable_stmt)
        if self.enable_stmt_default != enable_stmt_current:
            self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.enable_stmt}={self.enable_stmt_default}')
        show_enable_stmt = self.common.show_param(self.enable_stmt)
        log_min_current = self.common.show_param(self.log_min)
        if self.log_min_default != log_min_current:
            self.primary_sh.execute_gsguc(
                'reload', self.constant.GSGUC_SUCCESS_MSG,
                f'{self.log_min}={self.log_min_default}')
        show_log_min = self.common.show_param(self.log_min)
        self.logger.info("-----断言teardown-----")
        self.assertIn(self.constant.TABLE_DROP_SUCCESS,
                      drop_msg, '执行失败' + text_1)
        self.assertEquals(show_enable_stmt, self.enable_stmt_default,
                          '执行失败' + text_2)
        self.assertEquals(show_log_min, self.log_min_default, '执行失败' + text_2)
        self.logger.info(f"-----{os.path.basename(__file__)} end-----")
